﻿using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UIElements;
public class PenController : MonoBehaviour
{
    [SerializeField] private LayerMask slotLayerMask;
    public static PenController instance;
    /// <summary>
    /// 当前的笔头
    /// </summary>
    public GameObject penHead;

    private  float rayCastDis = 100f;

    /// <summary>
    /// 射线检测初始位置
    /// </summary>
    private GameObject rayGame;
    public bool isDraw = false;
    private bool isMoving = false;
    /// <summary>
    /// 是否边界移动结束，是否在边界移动中
    /// </summary>
    private bool  isMovingToBoundary=false;//isboundary =true ,

    private Vector3 lastPosition;
    /// <summary>
    ///  静止判定阈值
    /// </summary>
    private float stationaryThreshold = 0.01f;
    private float stationaryTime = 0f;
    private float requiredStationaryTime = 0.2f; // 需要静止的时间
    /// <summary>
    ///当前需要涂的数字（从1开始）
    /// </summary>
    public string currentTargetNumber; 

    public float returnSpeed = 5f; // 归位速度
    private Vector2? touchStartPosition;  // 可空的触摸起始位置
    public float moveSensitivity = 0.05f; // 移动灵敏度
    /// <summary>
    /// 触摸起始位置
    /// </summary>
    private  Touch touch;

    /// <summary>
    /// 笔头类型 单个，3横，3纵
    /// </summary>
    private Transform Single, Tri_Vertical, Tri_Horizontal;
    private  PenMode currentPenMode = PenMode.Single; // 默认单点模式
    /// <summary>
    /// 对应射线
    /// </summary>
    private List<Vector3> penTips;
    /// <summary>
    /// 网格大小
    /// </summary>
    public float tileSize = 1f;
    /// <summary>
    /// 边界内边距
    /// </summary>
    public float padding = 0.1f;
    // 计算出的地图边界
    private float minX, maxX, minZ, maxZ;

    
    public float smoothTime = 0.01f; // 调整此值控制平滑时间（秒）
    private Vector3 velocity = Vector3.zero;
    /// <summary>
    /// 宝石预制键，（砖石，五边型，八边型）
    /// </summary>
    private GameObject TestGem1, TestGem2, TestGem;
    /// <summary>
    /// 笔头位置
    /// </summary>
    private Transform PenHeadPos;
    /// <summary>
    /// 是否开始游戏,是否结束游戏
    /// </summary>
    public  bool isStartTheGame=true, isFinishTheGame=false;

    /// <summary>
    /// 屏幕当前中心点
    /// </summary>
    private Vector3 targetPosition, _targetPosition;
    /// <summary>
    /// 笔上升位置
    /// </summary>
    private Vector3 FinishThePos;
    /// <summary>
    /// 笔高度
    /// </summary>
    private float penHeight=0.5f;
    /// <summary>
    /// 手指是否在拖动
    /// </summary>
    private bool isDrag = false;


    /// <summary>
    /// 边界返回位置
    /// </summary>
    private Vector3 targetBoundaryPos;
    /// <summary>
    /// 边界返回移动速度
    /// </summary>
    private float moveSpeed = 3f;
    private float moveProgress = 0f;


    private void Awake()
    {
        if(instance==null)
        {
            instance = this;
        }
        Single = transform.Find("Tool Modes/Single");
        Tri_Vertical = transform.Find("Tool Modes/Tri_Vertical");
        Tri_Horizontal = transform.Find("Tool Modes/Tri_Horizontal");
        rayGame= transform.Find("Hadle Model/Diamonds Pen").gameObject;
        PenHeadPos= transform.Find("Tool Modes/Single/Spawn Point");
        TestGem1 = transform.Find("Tool Modes/Single/Spawn Point/TestGem 1").gameObject;
        TestGem2 = transform.Find("Tool Modes/Single/Spawn Point/TestGem 2").gameObject;
        TestGem = transform.Find("Tool Modes/Single/Spawn Point/TestGem").gameObject;

    }

    private  void Start()
    {
        lastPosition = transform.position;
    }


    private void Update()
    {
        // CheckMovement();
        if (!isDraw && !IsPointerOverUI() && isStartTheGame)//&& !isMoving 
        {
            TryDraw();
            //CheckRaycasts();
        }
        if (!IsPointerOverUI() && !isMovingToBoundary && isStartTheGame && !isFinishTheGame && !isDraw&&!MainCamera.instance.useSmoothMovement) // 只有不在UI上时才允许移动
        {
            Move();
        }

        pen_Fall();

        pen_Rise();

        TryStartBoundaryMove();

        if (isMovingToBoundary && isStartTheGame)
        {
            SmoothMoveToBoundary();
        }
    }

    /// <summary>
    /// 笔上升
    /// </summary>
    private void pen_Rise()
    {
        if (isFinishTheGame && !isDraw && isStartTheGame)
        {
            if (Vector3.Distance(transform.position, targetPosition) > 0.1f)
            {
                transform.position = Vector3.Lerp(transform.position, targetPosition, 1f * Time.deltaTime);
            }
            else
            {
                isFinishTheGame = false;
            }

        }
    }

    /// <summary>
    /// 笔下落
    /// </summary>
    private void pen_Fall()
    {
        if (!isStartTheGame && !isDraw)
        {
            if (Vector3.Distance(transform.position, new Vector3(transform.position.x, penHeight, transform.position.z)) > 0.1f)
            {
                transform.position = Vector3.Lerp(transform.position, targetPosition, 1f * Time.deltaTime);
            }
            else
            {
                isStartTheGame = true;
            }
        }
    }


    /// <summary>
    /// 完成游戏打开笔上升开关
    /// </summary>
    public void FinishTheGame()
    {
        isDraw = false;
        targetPosition = new Vector3(targetPosition.x, 100, targetPosition.z);
        isFinishTheGame = true;
       
    }


    /// <summary>
    /// 进入游戏降下笔
    /// </summary>
    /// <param name="_columns"></param>
    /// <param name="_rows"></param>
    /// <param name="_pos"></param>
    public void lowerPen(int _columns, int _rows, Vector3 _pos)
    {
       
        isFinishTheGame = false;
        isDraw = false;
        targetPosition = _pos + new Vector3(_columns / 2f, 0, -_rows / 2f);
        isStartTheGame = false;
        isMovingToBoundary = false;
        transform.position = new Vector3(targetPosition.x, 20, targetPosition.z);

    }

    

 



    // 计算地图边界（在初始化或地图变化时调用）
    public void CalculateBoundaries(int rows, int columns, Vector3 startPos)  
    {
       
        float mapWidth = columns * tileSize;
        float mapHeight = rows * tileSize;
        // 计算实际边界（考虑padding）
        minX = startPos.x + padding;
        maxX = startPos.x + mapWidth - padding;
        minZ = startPos.z - mapHeight + padding;  // 注意：Z轴负方向延伸
        maxZ = startPos.z - padding;
    }


    /// <summary>
    /// 超过边界初始化参数
    /// </summary>
    private void TryStartBoundaryMove()
    {
        if (!isMoving && !isDraw && !isDrag && !isMovingToBoundary&& isStartTheGame)
        {
            // 通过CheckBoundary获取正确的目标位置
            if (CheckBoundary(out targetBoundaryPos))
            {
                moveProgress = 0f;
                isMovingToBoundary = true;
                
                // 调试日志（可选）
                Debug.Log($"开始边界移动，目标位置：{targetBoundaryPos}");
            }
        }
    }
    /// <summary>
    /// 判断是否超过边界
    /// </summary>
    /// <param name="clampedPosition"></param>
    /// <returns></returns>
    private bool CheckBoundary(out Vector3 clampedPosition)
    {
        clampedPosition = transform.position;

        // 边界有效性检查（更简洁的比较方式）
        if (maxX <= minX || maxZ <= minZ)
            return false;

        // 计算并返回修正后的位置
        clampedPosition = new Vector3(
            Mathf.Clamp(transform.position.x, minX, maxX),
            transform.position.y,
            Mathf.Clamp(transform.position.z, minZ, maxZ)
        );

        // 检查是否需要移动（使用平方距离比较更高效）
        return (transform.position - clampedPosition).sqrMagnitude > float.Epsilon;
    }

    /// <summary>
    /// 超过边界平滑移动
    /// </summary>
    private void SmoothMoveToBoundary()
    {
            // 更新移动进度（使用更平滑的时间控制）
            moveProgress = Mathf.Clamp01(moveProgress + Time.deltaTime * moveSpeed);

        // 应用平滑移动（使用SmoothStep更自然的缓动）
        transform.position = Vector3.Lerp(
            transform.position,
            targetBoundaryPos,
            Mathf.SmoothStep(0f, 1f, moveProgress)
        );

        // 移动完成检查（使用近似比较）
        if (Vector3.Distance(transform.position, targetBoundaryPos) < 0.1f)
        {
            isMovingToBoundary = false;
            transform.position = targetBoundaryPos; // 确保最终位置精确
        }
    }


    /// <summary>
    /// 判断是否在Ui上
    /// </summary>
    /// <returns></returns>
    private bool IsPointerOverUI()
    {
        if (EventSystem.current.IsPointerOverGameObject())
            return true;

        if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began)
        {
            return EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId);
        }

        return false;
    }

    /// <summary>
    /// 笔头上的宝石切换（砖石，五边型，八边型）
    /// </summary>
    public void SwitchGems()
    {
        if(!GameInit.instance.MapData.map_color.ContainsKey(currentTargetNumber))
        {
            return;
        }
        Color _c = Color.white;
        if (GameInit.instance.MapData.map_color.ContainsKey(currentTargetNumber))
        {
            (string, string, string) str = GameInit.instance.MapData.map_color[currentTargetNumber].Item1;
            // 安全解析 RGB 值（处理可能的格式错误）
            if (float.TryParse(str.Item1, out float r) &&
                float.TryParse(str.Item2, out float g) &&
                float.TryParse(str.Item3, out float b))
            {
                // 如果输入是 0-255 的整数，需归一化到 0-1
                if (r > 1f || g > 1f || b > 1f)
                {
                    r /= 255f;
                    g /= 255f;
                    b /= 255f;
                }
                _c = new Color(r, g, b);
            }
        }
        TestGem1.SetActive(false);
        TestGem2.SetActive(false);
        TestGem.SetActive(false);

        switch(GameInit.instance.MapData.map_color[currentTargetNumber].Item2)
        {
            case "砖石":
                TestGem1.SetActive(true);
                TestGem1.transform.Find("Cubie").transform.GetComponent<Renderer>().material.color = _c; 
                break;
            case "五边型":
                TestGem2.SetActive(true);
                TestGem2.transform.Find("Cubie").transform.GetComponent<Renderer>().material.color = _c; 
                break;
            case "八边型":
                TestGem.SetActive(true);
                TestGem.transform.Find("Cubie").transform.GetComponent<Renderer>().material.color = _c; 
                break;
        }
     
    }
    /// <summary>
    /// 判断物体位置是否在变化
    /// </summary>
    void CheckMovement()
    {
        // 计算当前帧移动距离
        float moveDistance = Vector3.Distance(transform.position, lastPosition);
        lastPosition = transform.position;

        // 判断是否在移动
        if (moveDistance > stationaryThreshold)
        {
            isMoving = true;
            stationaryTime = 0f;
        }
        else
        {
            stationaryTime += Time.deltaTime;
            if (stationaryTime >= requiredStationaryTime)
            {
                isMoving = false;
            }
        }
    }


    /// <summary>
    /// 移动输入
    /// </summary>
    void Move()
    {
        if (Input.touchCount > 0 && !isDraw)
        {
            touch = Input.GetTouch(0);

            if (touch.phase == TouchPhase.Began)
            {
                touchStartPosition = touch.position;
                isMoving = true;
                isDrag = true;
            }
            else if (touch.phase == TouchPhase.Moved && touchStartPosition.HasValue)
            {
                MoveObject(touch.position);
            }
            else if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
            {
                touchStartPosition = null;
                isDrag = false;
                isMoving = false;
            }
        }
    }

    /// <summary>
    /// 实现移动
    /// </summary>
    /// <param name="currentPosition"></param>
    void MoveObject(Vector2 currentPosition)
    {
        // 计算屏幕位置差值
        Vector2 delta = currentPosition - touchStartPosition.Value;

        // 计算世界空间移动方向（X轴和Z轴）
        Vector3 moveDirection = new Vector3(delta.x, 0, delta.y) * moveSensitivity;

        Vector3 vec = new Vector3(transform.position.x + moveDirection.x, transform.position.y, transform.position.z + moveDirection.z);
        // 更新目标位置
        transform.position = Vector3.SmoothDamp(transform.position, vec, ref velocity, smoothTime); // 替换为你的目标位置（Vector3）
       // CameraMove();
        touchStartPosition = currentPosition;
    }

    #region 切换笔头
    /// <summary>
    /// 切换笔头
    /// </summary>
    /// <param name="newMode"></param>
    public void SwitchPenMode(PenMode newMode)
    {
        currentPenMode = newMode;

        // 禁用所有笔头
        Single.gameObject.SetActive(false);
        Tri_Vertical.gameObject.SetActive(false);
        Tri_Horizontal.gameObject.SetActive(false);
        // 启用当前笔头
        switch (newMode)
        {
            case PenMode.Single:
                Single.gameObject.SetActive(true);
                penHead = Single.gameObject;
                break;
            case PenMode.Tri_Vertical:
                Tri_Vertical.gameObject.SetActive(true);
                penHead = Tri_Vertical.gameObject;
                break;
            case PenMode.Tri_Horizontal:
                Tri_Horizontal.gameObject.SetActive(true);
                penHead = Tri_Vertical.gameObject;
                break;
        }
        //penTips = GetPenTipPositions(); // 获取所有检测点
        
    }

    /// <summary>
    /// 对应笔头射线生成
    /// </summary>
    /// <returns></returns>
    private  List<Vector3> GetPenTipPositions()
    {
        List<Vector3> tips = new List<Vector3>();

        switch (currentPenMode)
        {
            case PenMode.Single:
                tips.Add(Single.transform.position); // 单点模式，只有笔尖
                break;
            case PenMode.Tri_Vertical:
                float verticalOffset = 0.1f; // 垂直间距
                tips.Add(Tri_Vertical.transform.position + Vector3.up * verticalOffset);
                tips.Add(Tri_Vertical.transform.position);
                tips.Add(Tri_Vertical.transform.position + Vector3.down * verticalOffset);
                break;
            case PenMode.Tri_Horizontal:
                float horizontalOffset = 0.1f; // 水平间距
                tips.Add(Tri_Horizontal.transform.position + Vector3.left * horizontalOffset);
                tips.Add(Tri_Horizontal.transform.position);
                tips.Add(Tri_Horizontal.transform.position + Vector3.right * horizontalOffset);
                break;
        }
        return tips;
    }
    /// <summary>
    /// 对应笔头的射线检测
    /// </summary>
    private void CheckRaycasts()
    {
        if (penTips == null)
        {
            return;
        }
        List<Slot> slots = new List<Slot>();
        foreach (Vector3 tipPos in penTips)
        {
            Ray ray = new Ray(tipPos, Vector3.down); // 向下发射射线
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, rayCastDis))
            {
                Slot slot = hit.transform.GetComponent<Slot>();
                if (slot != null && slot.CanPaint(currentTargetNumber))
                {
                    slots.Add(slot);
                    //slot.Paint();
                }
            }
            // 可选的：可视化射线（Debug 用）
            //Debug.DrawRay(tipPos, Vector3.down * rayCastDis, Color.red, 0.1f);
        }
       
        if (slots.Count > 0)
        {
            int num = 0;
            for (int i=0;i<slots.Count;i++)
            {
                if(slots[0].id==currentTargetNumber)
                {
                    num++;
                }
            }

            if(num==slots.Count)
            {
                isDraw = true;
                //StartCoroutine(Drawing(slots));
              
            }

        }
    }
    #endregion

    /// <summary>
    /// 单个射线检测
    /// </summary>
    void TryDraw()
    {
        // CapsuleCast - 胶囊体射线检测
        float radius = 0.25f;
        float height = 0.3f;
        // 计算胶囊体的两个端点（受旋转影响）
        Vector3 point1 = rayGame.transform.position + rayGame.transform.up * (height / 2);
        Vector3 point2 = rayGame.transform.position - rayGame.transform.up * (height / 2);
        if (Physics.CapsuleCast(point1, point2, radius,-rayGame.transform.up, out RaycastHit hit, 100f, slotLayerMask))
        {
            if (hit.collider.TryGetComponent<Slot>(out Slot slot))
            {
                // 增加空引用检查
                if (slot != null && slot.CanPaint(currentTargetNumber) && slot.gameObject.activeInHierarchy)
                {
                    // 防止重复触发
                    if (!isDraw)
                    {
                       
                        StartCoroutine(Drawing(slot));
                    }
                }
            }
        }
        Debug.DrawLine(point1, point2, Color.blue, 0.1f);

    }
    /// <summary>
    /// 设置当前涂改编号
    /// </summary>
    /// <param name="id"></param>
    public void Set_currentTargetNumber(string id)
    {
        if(!GameInit.instance.isComplete(id))
        {
            ChangePanel.changePanel.displayPenId(id);
            currentTargetNumber = id;
            SwitchGems();
        }
    }

    /// <summary>
    /// 笔头点击
    /// </summary>
    /// <param name="slot"></param>
    /// <returns></returns>
    IEnumerator Drawing(Slot slot)
    {
        isDraw = true;
        // 1. 归位动画（调整高度和速度）
        Vector3 targetAboveSlot = slot.transform.position + new Vector3(0f, penHeight, 0f);
        float moveDuration = 0.2f; // 持续时间减少以加速动画
        float elapsed = 0f;
        Vector3 moveStartPos = transform.position;

        //while (elapsed < moveDuration)
        //{
        //    transform.position = Vector3.Lerp(moveStartPos, targetAboveSlot, elapsed / moveDuration);
        //    elapsed += Time.deltaTime;
        //    yield return null;
        //}
        transform.position = targetAboveSlot;

        // 2. 下压动画（增加下压距离和速度）
        Vector3 startPos = penHead.transform.position;
        Vector3 downPos = startPos + new Vector3(0f, -1f, 0f);
        float pressDuration = 0.02f;//0.015f; // 持续时间减少
        elapsed = 0f;

        while (elapsed < pressDuration)
        {
            penHead.transform.position = Vector3.Lerp(startPos, downPos, elapsed / pressDuration);
            elapsed += Time.deltaTime;
            yield return null;
        }
        slot.Paint(true);
        if (GameInit.instance.DigitQuantity.ContainsKey(slot.id))
        {
            GameInit.instance.DigitQuantity[slot.id]++;
        }

        if (GameInit.instance.DigitQuantity.ContainsKey(slot.id))
        {
            if (GameInit.instance.pieceDigitQuantity[slot.id].Count <= GameInit.instance.DigitQuantity[slot.id])
            {
                if (isStartTheGame&& !isFinishTheGame)
                {
                    StartCoroutine(GameInit.instance._PlayNumberOneCompleteEffect(slot.id, GameInit.instance.pieceDigitQuantity));
                }
            }
        }

        AudioManager.Instance.Play("安装砖石");
        // 3. 抬起动画（加速返回）
        yield return new WaitForSeconds(0.01f); // 等待时间从0.01f减少
        elapsed = 0f;
        while (elapsed < pressDuration)
        {
            penHead.transform.position = Vector3.Lerp(downPos, startPos, elapsed / pressDuration); // 返回到原始位置
            elapsed += Time.deltaTime;
            yield return null;
        }
        penHead.transform.position = startPos; // 确保精确复位
        GameInit.instance.GetNextOne();
        //4.检查完成状态（保持不变）
        //if (AllSlotsPaintedForNumber(currentTargetNumber))
        //{
        //    //Set_currentTargetNumber(GameInit.instance.GetNextOne());
        //    //GameInit.instance.GetNextOne();
        //    //GameInit.instance.amount = 0f;
        //    //Debug.Log($"可以开始涂数字 {currentTargetNumber}！");
        //    //StagePanel.instance.SetNum(currentTargetNumber.ToString());
        //}

        if (Input.touchCount> 0)
        {
            touch = Input.GetTouch(0);
            touchStartPosition = touch.position;
        }
        isDraw = false;
    }

    /// <summary>
    /// 笔跳转
    /// </summary>
    public void PenJumpTo(Vector3 vec)
    {
        if(!isMovingToBoundary && isStartTheGame && !isFinishTheGame && !isDraw)
        {
            transform.position = new Vector3(vec.x, transform.position.y, vec.z);
        }
    }

    private bool AllSlotsPaintedForNumber(string targetNumber)
    {
        List<Slot> allSlots = GameInit.instance.Slot_list;
        foreach (Slot slot in allSlots)
        {
            if (slot.number.text == targetNumber && !slot.GetisPainted())//int.TryParse(slot.number.text, out displayedNumber) &&
            {
                return false; // 发现未涂的格子
            }
        }
        return true; // 全部已涂
    }
}